/*
 * main.c
 * 不同登陆人员实现进程切换
 * 
 */

/*头文件*/
//------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
//------------------------------------


/*宏定义*/
//------------------------------------
#define CODE_SIZE 16
#define USER_SIZE 10
//------------------------------------


/*结构体*/
//------------------------------------
char* cmd1 = "./admin";
char* cmd2 = "./lottery";
char* cmd3 = "./user";
char* manager_info="data/manager.txt";
char* user_info="data/user_info.txt";
//------------------------------------


/*函数声明*/
//------------------------------------
void get_all(char *user, char *pwd);
int log_in(char user[USER_SIZE],char pwd[CODE_SIZE]);
int sign_up(char user[USER_SIZE],char pwd[CODE_SIZE]);
void get_code(char* c);
void get_user(char *user) ;

//------------------------------------


/*主函数*/
//------------------------------------
int main(int argc, char **argv)
{
	int status,n;
	
	int who;
	char user[USER_SIZE],pwd[CODE_SIZE];
	while(1){
	who=0;
	system("clear"); //清屏
	printf("欢迎进入彩票系统！\n");
	printf("-----------------------------------------\n");
	printf("1.用户登陆\n");
	printf("2.用户注册\n");
	printf("0.退出\n");
	printf("-----------------------------------------\n");
	
	while(1){
	printf("请输入操作指令：");
	int choose; if(1!=scanf("%d",&choose))
	{while(getchar()!='\n');continue;}
	
	enum sign{out, in, up};
	switch(choose){
		case in: get_all(user,pwd);who=log_in(user,pwd);break;
		case up: who=sign_up(user,pwd);break;
		case out: system("clear"); exit(0);
		default: printf("input error!\n");break;
		}
	if(who)break;
	}
	printf("\n");
	
	/*创建子进程*/
	pid_t pid;
	if((pid = fork())<0){perror("fork error");exit(1);}
	else if(pid==0)
	{
		enum login{_admin=1, _lottery, _user};
		switch(who)
		{
			case _admin: 
			if(execlp(cmd1, cmd1,NULL)<0)
			{perror("execl error");exit(1);}break;
			case _lottery:
			if(execlp(cmd2, cmd2,NULL)<0)
			{perror("execl error");exit(1);}break;
			case _user:
			if(execlp(cmd3, cmd3,user,NULL)<0)
			{perror("execl error");exit(1);}break;
		}
		
	}
	wait(&status);
	if(WIFEXITED(status))n=WEXITSTATUS(status); //判断子程序退出标志为3时直接退出
	//printf("normal exit: %d\n", (n=WEXITSTATUS(status)));
	if(n==0)continue; //子程序正常退出，回到界面
	if(n==3)break; //子程序直接退出
	if(n==1){perror("exit error!");break;}
	printf("-----------------------------------------\n");
}
	return 0;
}

/* 函数功能：登陆
 * 形参：用户名，密码
 * 返回：who
 */
int log_in(char user[USER_SIZE],char pwd[CODE_SIZE])
{
	char user_sys[USER_SIZE],pwd_sys[CODE_SIZE]; 
	int user_balance=0;

		FILE* f_man=fopen(manager_info,"r");
		if(!f_man){perror("");exit(1);}
		
		fscanf(f_man,"%s %s",user_sys,pwd_sys);
		if(!(strcmp(user,user_sys)||strcmp(pwd,pwd_sys)))
		{fclose(f_man);return 1;}
		
		fscanf(f_man,"%s %s",user_sys,pwd_sys);
		if(!(strcmp(user,user_sys)||strcmp(pwd,pwd_sys)))
		{fclose(f_man);return 2;}
		
		fclose(f_man);
		FILE* f_user=fopen(user_info,"r");
		if(!f_user){perror("");exit(1);}
		
		while(EOF != fscanf(f_user,"%s %s %d",user_sys,pwd_sys,&user_balance))
		if(!(strcmp(user,user_sys)||strcmp(pwd,pwd_sys)))
		{fclose(f_user);return 3;}
		
		printf("帐号不存在!\n");fclose(f_user);

	return 0;
}

/* 函数名：注册
 * 形参：用户名，密码
 * 返回：who
 */
int sign_up(char user[USER_SIZE],char pwd[CODE_SIZE])
{
	char pwd_check[CODE_SIZE];
	char user_check[CODE_SIZE];
	int balance;
	
	get_user(user);
	//用户名重复确认
	FILE* f_user=fopen(user_info,"r+");
	if(!f_user){perror("");exit(1);}
	while(fscanf(f_user,"%s %s %d",user_check,pwd_check,&balance)>0)
	if(!strcmp(user_check,user)){printf("用户名已存在！\n");fclose(f_user);return 0;}
	
	printf("请输入密码(按q退出注册)\n");
	get_code(pwd);
	if(!strcmp(pwd,"q"))return 0;
	//注册密码确认
	while(1){
		printf("请再输入密码确认\n");
		get_code(pwd_check);
		if(!strcmp(pwd_check,pwd))break;
	}
	
	fprintf(f_user,"%s %s %d\n",user,pwd,0); //注意加上'\n'
	fclose(f_user);
	printf("注册成功！1秒后进入系统 ...\n");
	sleep(1);
	
	return 3;
}

/* 函数名：获取密码(隐藏显示)
 * 形参：密码字符串指针
 * 返回：
 */
void get_code(char* c) 
{
	while(1){
	system("stty -icanon"); //stty -icanon 设置一次性读完操作，如使用getchar()读操作，不需要按enter
	system("stty -echo"); //stty -echo 设置命令不被显示
	printf("输入密码(不大于%d个字符):",CODE_SIZE-1);
	int i=0;
	while(1){
		char ch;
		ch = getchar();
		if((ch  == 127 || ch  == 8) && i>0)//当有键入时，按键delete或backspace时，删除一位
			{
				printf("\b");	//这里是删除一个，通过输出回撤符 /b，回撤一格，
				printf(" ");	//再显示空格符把刚才的*给盖住，
				printf("\b");	//然后再 回撤一格等待录入。	
				--i; //此时i指在空格处
			}
		else if(ch==10 || ch == 13)//当键入的为换行时
			{
				c[i] = '\0';//将字符串以'\0'结尾
				break;
			}
		else{c[i]=ch;printf("*");++i;} //成功读取时
	}
	system("stty echo"); // stty echo 取消不显设置
	system("stty icanon"); //stty icanon 取消设置
	printf("\n");
	if(i>0 && i<CODE_SIZE)break;
	}
	return;
}

/* 函数名：获取用户名
 * 形参：用户名字符串
 * 返回：
 */
void get_user(char *user) 
{
	printf("账户名：");
	scanf("%s",user);
	while(getchar()!='\n');
	return;
}

/* 函数名：获取用户名和字符串
 * 形参：用户名，密码
 * 返回：
 */
void get_all(char *user, char *pwd)
{
	get_user(user);
	get_code(pwd);
}
